package com.eternal.webSocke;/**
 * @Title: Demo
 * @ProjectName notest
 * @Description: TODO
 * @author Eternal
 * @date 2018/12/15 21:57
 */

import com.eternal.webSocke.encoder.ServerEncoder;
import com.eternal.webSocke.vo.MessageVo;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @Class GroupChatWebSocket
 * @Description: TODO
 * @Author Eternal
 * @Version
 * @date 2018/12/15 21:57
 */
@ServerEndpoint(value = "/websocket/groupChat/{roomId}/{userId}", encoders = {ServerEncoder.class})
@Component
public class GroupChatWebSocket {

    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static final Map<String, Integer> onlineCount = new HashMap<>();

    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。
    private static final Map<String, CopyOnWriteArraySet<GroupChatWebSocket>> rooms = new HashMap();
    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
    private String userId;
    private String roomId;
    // private String openId;

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(@PathParam(value = "roomId") String roomId, @PathParam(value = "userId") String userId, Session session) {

        this.session = session;
        CopyOnWriteArraySet<GroupChatWebSocket> webSocketSet = rooms.get(roomId);
        this.roomId = roomId;
        this.userId = userId;
        // this.openId = openId;
        if (webSocketSet == null) {
            synchronized (rooms) {
                if (!rooms.containsKey(roomId)) {
                    webSocketSet = new CopyOnWriteArraySet<>();
                    rooms.put(roomId, webSocketSet);
                }
            }
        }

        webSocketSet.add(this);
        addOnlineCount(roomId);
        MessageVo messageVo = new MessageVo();
        messageVo.setCode("001");
        messageVo.setUserId(userId);
        messageVo.setMessage(userId + "进入" + roomId + "号房间!当前人数：" + getOnlineCount(roomId));
        messageVo.setHeadImgUrl("http://118.31.32.184:82/headImg/"+userId+".png");
        mass(messageVo, roomId);

    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        CopyOnWriteArraySet<GroupChatWebSocket> webSocketSet = rooms.get(roomId);
        if (webSocketSet != null) {
            webSocketSet.remove(this);
            subOnlineCount(roomId); //在线数减1
            System.out.println("有一连接关闭！当前在线人数为" + getOnlineCount(roomId));
        }


    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        CopyOnWriteArraySet<GroupChatWebSocket> friends = rooms.get(roomId);
        if (friends != null) {
            MessageVo messageVo = new MessageVo();
            messageVo.setCode("001");
            messageVo.setUserId(userId);
            messageVo.setMessage(message);
            messageVo.setHeadImgUrl("http://192.168.1.10:82/headImg/"+userId+".png");
            mass(messageVo, roomId);
        }

    }

    /**
     * 发生错误时调用
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }


    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }


    public void sendMessage(MessageVo messageVo) throws IOException, EncodeException {
        this.session.getBasicRemote().sendObject(messageVo);
    }

    public void mass(MessageVo messageVo, String roomId) {
        System.out.println("来自客户端的消息:" + messageVo.toString());
        CopyOnWriteArraySet<GroupChatWebSocket> friends = rooms.get(roomId);
        if (friends != null) {
            try {
                for (GroupChatWebSocket item : friends) {
                    item.sendMessage(messageVo);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (EncodeException e) {
                e.printStackTrace();
            }
        }


    }


    public static synchronized int getOnlineCount(String roomId) {

        return onlineCount.get(roomId);
    }

    public static synchronized void addOnlineCount(String roomId) {
        Integer integer = onlineCount.get(roomId);
        if (integer == null) {
            integer = 0;
        }
        integer++;
        onlineCount.put(roomId, integer);

    }

    public static synchronized void subOnlineCount(String roomId) {
        Integer integer = onlineCount.get(roomId);
        if (integer == null) {
            integer = 1;
        }
        integer--;
        onlineCount.put(roomId, integer);
    }

}
